package com.atguigu.redis_springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author Administrator
 */
@RestController
@RequestMapping("/test")
public class RedisTestController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @GetMapping("/redis")
    public String testRedis(){
//        设置值到redis
    stringRedisTemplate.opsForValue().set("name","大哥花生豆");
//    从redis中获取值
        String name = stringRedisTemplate.opsForValue().get("name");
        return name;
    }
    @GetMapping("/lock")
    public void testLock(){
        String  uuid = UUID.randomUUID().toString();
        //访问skuId为25号的商品
        String skuId = "25";
        //锁住的是每个商品的数据
        String locKey = "lock"+skuId;
//        1.获取锁
        Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent("lock",uuid,125, TimeUnit.SECONDS);
//        2.获取锁成功，查询num的值
        if(lock){
            //获取缓存中的num数据
            Object value = stringRedisTemplate.opsForValue().get("num");
//            2.1判断num为空return
            if (StringUtils.isEmpty(value)){
                return;
            }
//            2.2有值就转成int
            int num = Integer.parseInt(value+"");
//            2.3把redis的num加1,放入缓存
            stringRedisTemplate.opsForValue().set("num",String.valueOf(++num));
//            2.4释放锁，del
            //使用lua脚本来删除锁
            //定义lua脚本
            String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
            //使用redis执行lua
            DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
            redisScript.setScriptText(script);
            //设置返回值类型为Long
            redisScript.setResultType(Long.class);
            stringRedisTemplate.execute(redisScript, Arrays.asList(locKey),uuid);
        }else {
//            3.获取锁失败，每隔0.1秒再获取
            try {
                Thread.sleep(100);
                testLock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
